import MyUtil
import os
import const
import cls
import time
import pandas as pd
import numpy as np
import HisData
import datetime
import csv
# --------------------------------create all stocks instance---------------------------------------------------------

class stock_back(cls.stock):
    def __init__(self,symbol,name):
        cls.stock.__init__(self, symbol, name)
        self.bdl_ma5_2 = 0      # 前日波动率
        self.bdl_ma30_2 = 0
        # self.day60bi = 0
        # self.relative_pos2 = 99999
        #     1  连续tick：当前TICK 满足分钟量比<4 分钟hs>0.04 的连续TICK数量 （连续三个TICK不满足认为不连续）
        #     2  tick总数: 当前TICK 满足分钟量比<4 分钟hs>0.04 的TICK总数
        #     3  增加连续tick涨幅：当前tick的价格比上连续TICK的第一个价格的涨幅
        #     4  NOWHIGH 指标
        #     5  增加分钟涨幅2  计算方法 计算当前价和一分钟最低价的涨幅。
        #     6  增加分钟涨幅3   计算方法 计算当前价离一分钟最高价的涨幅
        #     7  秒笔数：transection的数量除以总的秒数
        #     8  当前分钟笔数：当前一分钟TRANSECTION的数量
        self.good_tick_time = 0 #  上一个TICK 满足分钟量比<4 分钟hs>0.04的时间(化成秒)
        self.good_tick_close = 0
        self.low_onemin = 0
        self.high_onemin = 0

        #
        self.good_ticks_contin = 0  #连续tick
        self.good_ticks_cnt = 0     #当前TICK 满足分钟量比<4 分钟hs>0.04 的TICK总数
        self.good_ticks_zf = 0      #当前tick的价格比上连续TICK的第一个价格的涨幅
        self.nowhigh = 0
        self.now_low_onemin = 0      #5  增加分钟涨幅2  计算方法 计算当前价和一分钟最低价的涨幅。
        self.now_high_onemin = 0    #6  增加分钟涨幅3   计算方法 计算当前价离一分钟最高价的涨幅
        self.bishu_div_sec = 0      #7  秒笔数：transection的数量除以总的秒数
        self.bishu_onemin = 0       #8  当前分钟笔数：当前一分钟TRANSECTION的数量

    def setHisData_add(self,data):
        if 'bdl_ma5_2' in data:
            self.bdl_ma5_2 = data['bdl_ma5_2']
        if 'bdl_ma30_2' in data:
            self.bdl_ma30_2 = data['bdl_ma30_2']
        # if 'day60bi' in data:
        #     self.day60bi = data['day60bi']
        # if 'relative_pos2' in data:
        #     self.relative_pos2 = data['relative_pos2']




def create_stock_inst(symbols, stock_inst_dic, blockofstock, back_test_day , day_line_dic):

    stock_inst_dic.clear()      # 清空字典

    for item in symbols:
        symbol_code = item[1]
        symbol_name = item[2]

        # 设置历史数据
        mhisdata = getStockHisInfo(symbol_code, back_test_day)
        new_cls = stock_back(symbol_code, symbol_name)

        if mhisdata != None:
            new_cls.setHisData(mhisdata)
            new_cls.setHisData_add(mhisdata)
            day_line_dic[symbol_code] = {}
            if 'tommorow_o' in mhisdata:
                day_line_dic[symbol_code]['tommorow_o']= round(mhisdata['tommorow_o'],2)
            if 'tommorow_c' in mhisdata:
                day_line_dic[symbol_code]['tommorow_c']=round(mhisdata['tommorow_c'],2)
            if 'today_close' in mhisdata:
                day_line_dic[symbol_code]['today_close']= round(mhisdata['today_close'],2)
            try:
                # 设置板块
                mblockofstock = blockofstock[symbol_code]
                new_cls.setBlockData(mblockofstock)
            except Exception as e:
                MyUtil.print_error(e)
                continue
        stock_inst_dic[symbol_code] = new_cls


#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#                           对外接口 步骤3： getStockHisInfo
#   paramter : symbol
#  获取步骤2目录STOCK_HIS_INFO的 个股历史信息，
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@


def getStockHisInfo(symbol, back_test_day):
    try:
        stock_his_info_path = const.STOCK_HIS_BACK_INFO + os.sep + str(back_test_day) + os.sep + symbol + '.txt'
        if os.path.exists(stock_his_info_path):
            info = MyUtil.getInfo(stock_his_info_path)
            return info
        else:
            print('there is no file or no folder !!:', stock_his_info_path)
    except Exception as e:
        MyUtil.print_error(e)


#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#                           离线处理 getFinanceInfo
#   paramter : None
#  返回字典 finance_dic
#  key 流通盘  : ltp
#  key 上市日期 :PublicDate
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
def getFinanceInfo(back_test_day, finance_csv_dic): # 获取离线文件夹中的最新财务信息csv内容
    finance_dic = {}
    if os.path.exists(const.FINANCE):
        filesList = os.listdir(const.FINANCE)
        if filesList==[]:
            print('there is no file in FINANCE Folder!')
            return finance_dic
        back_test_day_int = int(back_test_day)
        first_file_day = int(filesList[0].split('fin')[0])
        day_diff = abs(back_test_day_int - first_file_day)
        day_idx = 0
        for i in range(len(filesList)):
            item = filesList[i]
            file_day = int(item.split('fin')[0])
            diff_tmp = abs(file_day - back_test_day_int)
            if diff_tmp < day_diff:
                day_diff = diff_tmp
                day_idx = i

        newestfile = filesList[day_idx]
        if back_test_day not in finance_csv_dic:
            df = pd.read_csv(const.FINANCE+os.sep+newestfile, encoding='gbk',dtype={'证券代码':np.str,'上市日期':np.str})
        else:
            df = finance_csv_dic[back_test_day]
        dflist = df.values
        for item in dflist:
            code = str(item[1]).zfill(6)
            finance_dic[code] = {}
            finance_dic[code]['ltp'] = float(item[2])
            finance_dic[code]['PublicDate'] = int(item[6]) #上市日期
    return finance_dic

#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#                           对外接口  步骤2： 离线处理 makeStockHisInfo
#   paramter : symbols
#  对在线获取历史数据进行处理，生成个股历史信息，存放在STOCK_HIS_INFO目录下
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@


def makeStockHisInfo_batch(symbols, back_test_day_batch, cntl_q):
    csv_data_dic = {}
    finance_csv_dic = {}
    for back_test_day in back_test_day_batch:
        makeStockHisInfo(symbols, back_test_day, csv_data_dic, finance_csv_dic)
    cntl_q.put({'event': 'exit', 'pid': os.getpid()})

def makeStockHisInfo(symbols, back_test_day, csv_data_dic, finance_csv_dic):
    start = time.time()
    stock_his_info_path = const.STOCK_HIS_BACK_INFO + os.sep + back_test_day
    if not os.path.exists(stock_his_info_path):
        os.makedirs(stock_his_info_path)
    finance_dic = getFinanceInfo(back_test_day, finance_csv_dic)
    for symbol in symbols:
        try:
            if os.path.exists(stock_his_info_path+os.sep+symbol+'.txt'):
                #os.remove(stock_his_info_path+os.sep+symbol+'.txt')
                continue

            if not os.path.exists(const.KLINE400 + os.sep + symbol+'.csv'):
                print('there is no this stock in kline400 folder!!!!:',symbol)
                continue
            if not symbol in finance_dic:
                print('there is no this stock in finance_dic!!!:', symbol)
                continue
            StockHisInfoDic ={}
            try:
                StockHisInfoDic['ltp'] = finance_dic[symbol]['ltp']  # 流通盘
                StockHisInfoDic['PublicDate'] = finance_dic[symbol]['PublicDate']  # 上市日期
            except Exception as e:
                print('finance data abnornal!!!:',symbol)
                continue
            dayline_dic = getDayLineInfo(symbol, StockHisInfoDic['PublicDate'], back_test_day, csv_data_dic)
            if dayline_dic=={}:
                print('dayline data abnormal!!:',symbol)
                continue

            for key in dayline_dic:
                StockHisInfoDic[key] = dayline_dic[key]

            try:
                kline_dic_1000 = get_1000day_line_info(symbol, dayline_dic['ma5_c'],back_test_day)
                # kline_dic_1000={}
                # kline_dic_1000['relative_pos']=0
                # kline_dic_1000['high_low_1000_zf']=0
                # kline_dic_1000['now_low_1000_zf'] = 0
                StockHisInfoDic['relative_pos'] = kline_dic_1000['relative_pos']
                StockHisInfoDic['high_low_1000_zf'] = kline_dic_1000['high_low_1000_zf']
                StockHisInfoDic['now_low_1000_zf'] = kline_dic_1000['now_low_1000_zf']

                StockHisInfoDic['relative_pos2'] = kline_dic_1000['relative_pos2']
                StockHisInfoDic['high_low_500_zf'] = kline_dic_1000['high_low_500_zf']
                StockHisInfoDic['now_low_500_zf'] = kline_dic_1000['now_low_500_zf']
            except Exception as e:
                print('get_1000day_line_info!!!:', symbol)
                MyUtil.print_error(e)

            f = open(stock_his_info_path + os.sep + symbol + '.txt', 'w')
            f.write(str(StockHisInfoDic))
            f.close()
        except Exception as e:
            MyUtil.print_error(e)
            # MyUtil.WrieTxtLogFile('makeStockHisInfo error!!:'+str(symbol))
            continue
    print('makeStockHisInfo cost time:', round(time.time()-start,2))

#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#                           对外接口 步骤1： getHisDataOnLine
#   paramter : None
#  在线获取历史数据，股票列表，K线数据，财务数据
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
def getHisDataOnLine():
    mgetDataOnline = HisData.getDataOnline()
    mgetDataOnline.getAllStockCodeTDX_Online()
    symbols = MyUtil.getAllStockList()
    # mgetDataOnline.GetFinanceInfo_Online(symbols)
    mgetDataOnline.getDayKline_Online(symbols, 460)
    mgetDataOnline = None
    symbols=None



#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#                           离线处理 getDayLineInfo
#   paramter : symbol,PublicDate
#  返回字典 kline_info_dic
#  key 半年最高价  : hhigh_120
#  key 年最高价,最低价 :hhigh_220,llow_220
#  key 均量 ma5_v，ma10_v，ma20_v
#  key 均价 ma10_c，ma10_c，ma10_c
#  key 涨停次数 zt_cnt = 0 停后次日收盘大于涨停价 zt_good = 0

#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
def getDayLineInfo(symbol, PublicDate, back_test_day, csv_data_dic):
    kline_info_dic = {}
    try:
        if not symbol in csv_data_dic:
            df0 = pd.read_csv(const.KLINE400 + os.sep + symbol+'.csv', encoding='gbk')
            csv_data_dic[symbol] = df0
        else:
            df0= csv_data_dic[symbol]
            # print('symbol in csv_data_dic:', symbol)
        df0[['时间']] = df0[['时间']].astype(int)
        df = df0[df0['时间'] < int(back_test_day)]
        df_test_day = df0[df0['时间'] == int(back_test_day)].values
        df_test_day_tommorow = df0[df0['时间'] > int(back_test_day)].values
        lines = df.shape[0]
        if lines<10:
            #print('数据量不足10行 可能是新上市股票!!:',symbol)
            return kline_info_dic
        ##############################获取历史半年最高价#################
        hhigh_120 = 0
        if lines >= 120:
            hhigh_120 = df['最高价'].rolling(120).max()
        else:
            hhigh_120 = df['最高价'].rolling(lines - 1).max()

        kline_info_dic['hhigh_120'] = hhigh_120.tolist()[-1]
        ##############################获取历史年最高价,最低价################
        hhigh_220 = 0
        if lines >= 220:
            hhigh_220 = df['最高价'].rolling(220).max()
        else:
            hhigh_220 = df['最高价'].rolling(lines - 1).max()

        kline_info_dic['hhigh_220'] = hhigh_220.tolist()[-1]
        llow_220 = 0
        if lines >= 220:
            llow_220 = df['最低价'].rolling(220).min()     #20180807 modify max to min
        else:
            llow_220 = df['最低价'].rolling(lines - 1).min()

        kline_info_dic['llow_220'] = llow_220.tolist()[-1]

        ####################################5-10-20均量#######################
        ma5_v= 0
        #ma4_v = 0
        ma10_v=0
        ma20_v=0
        if lines > 5:
            ma5_v = df['成交量'].rolling(5).mean()
            #ma4_v = df['成交量'].rolling(4).mean()
        else:
            ma5_v = df['成交量'].rolling(lines - 1).mean()
            #ma4_v = ma5_v
        if lines> 10:
            ma10_v = df['成交量'].rolling(10).mean()
        else:
            ma10_v = df['成交量'].rolling(lines - 1).mean()
        if lines > 20:
            ma20_v = df['成交量'].rolling(20).mean()
        else:
            ma20_v = df['成交量'].rolling(lines - 1).mean()
        #kline_info_dic['ma4_v'] = ma4_v.tolist()[-1]
        kline_info_dic['ma5_v'] = ma5_v.tolist()[-1]
        kline_info_dic['ma10_v'] = ma10_v.tolist()[-1]
        kline_info_dic['ma20_v'] = ma20_v.tolist()[-1]
        ####################################5-10-20均价#######################
        ma5_c = 0
        ma10_c = 0
        ma20_c = 0
        if lines > 5:
            ma5_c = df['收盘价'].rolling(5).mean()
        else:
            ma5_c = df['收盘价'].rolling(lines - 1).mean()
        if lines > 10:
            ma10_c = df['收盘价'].rolling(10).mean()
        else:
            ma10_c = df['收盘价'].rolling(lines - 1).mean()
        if lines > 20:
            ma20_c = df['收盘价'].rolling(20).mean()
        else:
            ma20_c = df['收盘价'].rolling(lines - 1).mean()
        kline_info_dic['ma5_c'] = ma5_c.tolist()[-1]
        kline_info_dic['ma10_c'] = ma10_c.tolist()[-1]
        kline_info_dic['ma20_c'] = ma20_c.tolist()[-1]
        ####################################历史一年涨停次数#######################
        zt_cnt = 0
        zt_good = 0 #涨停后次日收盘大于涨停价
        df['zt']=df['收盘价']*1.1
        df['zt'] = df['zt'].round(2)
        closelist =df['收盘价'].tolist()
        ztlist = df['zt'].tolist()
        kp_zt_flg =False
        try:
            PublicDate_str=str(PublicDate)
            date1 = time.strptime(PublicDate_str, "%Y%m%d")
            date1 = datetime.datetime(date1[0], date1[1], date1[2])
            first_date_str = str(df.iat[0,0])
            date2 = time.strptime(first_date_str, "%Y%m%d")
            date2 = datetime.datetime(date2[0], date2[1], date2[2])
            if abs((date2 - date1).days)<10: #开盘10天内
                if closelist[1] >= ztlist[0]:
                    #print('new stock:',symbol)
                    kp_zt_flg=True
        except Exception as e:
            MyUtil.print_error(e)
        begin_day=1
        if lines <210:
            begin_day = 20

        if lines>20:
            day220_range = 220
            if len(closelist) < day220_range:
                day220_range = len(closelist)
            for price_i in range(begin_day,day220_range):
                if closelist[price_i]<ztlist[price_i-1]:            #应该是open_list ?
                    kp_zt_flg=False
                if closelist[price_i]==ztlist[price_i-1] and kp_zt_flg==False:
                    zt_cnt = zt_cnt+1
                    if closelist[price_i+1]>closelist[price_i]:
                        zt_good = zt_good+1
        kline_info_dic['zt_cnt'] =zt_cnt
        kline_info_dic['zt_good'] = zt_good
        ##
        kline_info_dic['zf_last']=0
        if lines>3:
            df['zf'] = 100 * (df['收盘价'] - df['收盘价'].shift(1)) / (df['收盘价'].shift(1))
            zflist = df['zf'].tolist()
            kline_info_dic['zf_last_1'] = round(zflist[-1],2)
        ##############################################################################################################
        #
        ##############################获取历史30 day==【收盘价】的最高###########################################################
        ref_c = closelist[-1]
        hhigh30 = 0
        if lines >= 30:
            hhigh30 = df['收盘价'].rolling(30).max()
        else:
            if lines > 1:
                hhigh30 = df['收盘价'].rolling(lines - 1).max()
            else:
                #print('day lines is less than 1:', code)
                pass
        if ref_c!=0:
            hhigh30=hhigh30.tolist()[-1]
            kline_info_dic['day30bi']= 100*(ref_c-hhigh30)/ref_c
        else:
            kline_info_dic['day30bi']=-999
        ##############################获取历史10 day close最低###########################################################
        if lines >= 10:
            llow10 = df['收盘价'].rolling(10).min()
        else:
            if lines > 1:
                llow10 = df['收盘价'].rolling(lines - 1).min()
            else:
                # print('day lines is less than 1:', code)
                pass
        try:
            llow10=llow10.tolist()[-1]
            kline_info_dic['day10bi'] = 100 * (ref_c - llow10) / llow10
        except:
            kline_info_dic['day10bi']=-999
        ##############################获取历史20 day close最低###########################################################
        if lines >= 20:
            llow20 = df['收盘价'].rolling(20).min()
        else:
            if lines >= 1:
                llow20 = df['收盘价'].rolling(lines - 1).min()
            else:
                # print('day lines is less than 1:', code)
                pass
        try:
            llow20=llow20.tolist()[-1]
            kline_info_dic['day20bi'] = 100 * (ref_c - llow20) / llow20
        except:
            kline_info_dic['day20bi']=-999
        ##############################获取历史60 day close最低###########################################################
        if lines >= 60:
            llow60 = df['收盘价'].rolling(60).min()
        else:
            if lines >= 1:
                llow60 = df['收盘价'].rolling(lines - 1).min()
            else:
                # print('day lines is less than 1:', code)
                pass
        try:
            llow60 = llow60.tolist()[-1]
            kline_info_dic['day60bi'] = 100 * (ref_c - llow60) / llow60
        except:
            kline_info_dic['day60bi'] = -999
        ##############################波动率###########################################################################
        try:
            df['bdl_1'] = 100*(df['最高价'] - df['最低价']) / (df['收盘价'].shift(1))
            df['bdl_2'] = 100*(df['最高价'] - df['收盘价'].shift(1)) / (df['收盘价'].shift(1))
            df['bdl'] = df.apply(lambda x: getmaxvalue(x.bdl_1, x.bdl_2), axis=1)
            df['bdl_ma30'] = df['bdl'].rolling(30).mean()
            df['bdl_ma5'] = df['bdl'].rolling(5).mean()
            del df['bdl_1']
            del df['bdl_2']
            del df['bdl']
            bdl_ma30=df['bdl_ma30'].tolist()[-1]
            bdl_ma5=df['bdl_ma5'].tolist()[-1]
            kline_info_dic['bdl_ma30'] = bdl_ma30
            kline_info_dic['bdl_ma5']=bdl_ma5
            # 前天
            bdl_ma30_2 = df['bdl_ma30'].tolist()[-2]
            bdl_ma5_2 = df['bdl_ma5'].tolist()[-2]
            kline_info_dic['bdl_ma30_2'] = bdl_ma30_2
            kline_info_dic['bdl_ma5_2'] = bdl_ma5_2
        except Exception as e:
            #MyUtil.print_error(e)
            pass

        # #########################################有效涨停30日######################################################
        zt_cs = 0    # 涨停次数
        wx_zt_cs = 0
        zt_cs_60 = 0
        try:
            high_list = df['最高价'].tolist()
            close_lst_len = len(closelist)
            if lines>60:
                for i in range(close_lst_len - 30, close_lst_len):
                    if closelist[i] == ztlist[i-1]:
                        zt_cs += 1
                for i in range(close_lst_len - 60, close_lst_len):
                    if closelist[i] < ztlist[i-1] and high_list[i] == ztlist[i-1]:
                        wx_zt_cs += 1
                for i in range(close_lst_len - 60, close_lst_len):
                    if closelist[i] == ztlist[i-1]:
                        zt_cs_60 += 1
        except Exception as e:
            MyUtil.print_error(e)
        kline_info_dic['zt_cs'] = zt_cs
        kline_info_dic['zt_cs_60'] = zt_cs_60
        kline_info_dic['wx_zt_cs'] = wx_zt_cs

        #  #############################获取历史20 day low最低###########################################################
        try:
            low_20 = 1.1111
            if lines >= 20:
                low_20_lst = df['最低价'].rolling(20).min()
            else:
                if lines >= 1:
                    low_20_lst = df['最低价'].rolling(lines - 1).min()
                else:
                    # print('day lines is less than 1:', code)
                    pass

            low_20 = low_20_lst.tolist()[-1]
            kline_info_dic['low_20'] = low_20

        except Exception as e:
            kline_info_dic['low_20'] = 1.111
            MyUtil.print_error(e)
        # #####################################zt_price#############################################################
        zt_price = 1.1111
        try:
            zt_price= ztlist[-1]
        except Exception as e:
            kline_info_dic['zt_price'] = 1.111
        kline_info_dic['zt_price'] = zt_price
        # ##########################################  tommorow price  ###########################################
        if len(df_test_day_tommorow) >= 1:
            kline_info_dic['tommorow_o'] = df_test_day_tommorow[0][1]
            kline_info_dic['tommorow_c'] = df_test_day_tommorow[0][2]
        else:
            if len(df_test_day) == 1:
                kline_info_dic['today_close'] = df_test_day[0][1]
    except Exception as e:
        MyUtil.print_error(e)
    return kline_info_dic
##########################
def getmaxvalue(a,b):
    if a>b:
        return a
    else:
        return b


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#                           离线处理 get1000DayLineInfo
#   paramter : symbol,last_close
#  返回字典 kline_info_dic
#  key 1000day最高价相对最低价涨幅  : high_low_1000_zf
#  key 1000day昨日收盘价相对最低价涨幅 :now_low_1000_zf
#  key 涨幅区间: relative_pos
#
#

# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# !!!!!这里还不完善,历史回测的时候,要以当时的价格进行前复权.

def get_1000day_line_info(symbol, last_close, back_test_day):
    kline_info_dic = {}
    try:
        if not os.path.exists(const.TX_1000DAY_QFQ_DATA + os.sep + symbol + '.csv'):
            return kline_info_dic
        df = pd.read_csv(const.TX_1000DAY_QFQ_DATA + os.sep + symbol + '.csv', encoding='gbk')
        df[['时间']] = df[['时间']].astype(int)
        df = df[df['时间'] < int(back_test_day)]
        lines = df.shape[0]
        if lines < 10:
            # print('数据量不足10行 可能是新上市股票!!:',symbol)
            return kline_info_dic
        ##############################获取历史最高价#################
        hhigh_1000 = 0
        if lines >= 1000:
            hhigh_1000 = df['最高价'].rolling(1000).max()
        else:
            hhigh_1000 = df['最高价'].rolling(lines - 1).max()

        hhigh_1000_price = hhigh_1000.tolist()[-1]

        hhigh_500 = 0
        if lines >= 500:
            hhigh_500 = df['最高价'].rolling(500).max()
        else:
            hhigh_500 = df['最高价'].rolling(lines).max()

        hhigh_500_price = hhigh_500.tolist()[-1]
        ##############################获取历史年最低价################
        llow_1000 = 0
        if lines >= 1000:
            llow_1000 = df['最低价'].rolling(1000).min()  # 20180807 modify max to min
        else:
            llow_1000 = df['最低价'].rolling(lines - 1).min()
        llow_1000_price = llow_1000.tolist()[-1]

        llow_500 = 0
        if lines >= 500:
            llow_500 = df['最低价'].rolling(500).min()
        else:
            llow_500 = df['最低价'].rolling(lines).min()
        llow_500_price = llow_500.tolist()[-1]
        #####################################################----相对涨幅xdzf
        kline_info_dic['high_low_1000_zf'] = 100 * (hhigh_1000_price - llow_1000_price) / llow_1000_price
        kline_info_dic['now_low_1000_zf'] = 100 * (last_close - llow_1000_price) / llow_1000_price
        kline_info_dic['relative_pos'] = 100 * round(kline_info_dic['now_low_1000_zf'] /
                                                     kline_info_dic['high_low_1000_zf'], 2)

        #####################################################----相对涨幅xdzf
        kline_info_dic['high_low_500_zf'] = 100 * (hhigh_500_price - llow_500_price) / llow_500_price
        kline_info_dic['now_low_500_zf'] = 100 * (last_close - llow_500_price) / llow_500_price
        kline_info_dic['relative_pos2'] = 100 * round(kline_info_dic['now_low_500_zf'] /
                                                      kline_info_dic['high_low_500_zf'], 2)

    except Exception as e:
        MyUtil.print_error(e)
    return kline_info_dic


def updataSelectionStock(mydic, mgrSeleList, STOCKS_INST_DIC,back_test_day):
    #
    #   这里实时数据只能用selecetion函数中的newDic的,也就是 这里的mgrSeleList,
    #   只有历史数据才能用 STOCKS_INST_DIC中的 切记!!!!!!!!!!!!!!!!
    #
    alldatalist = []
    alldatalist.append(const.line0_back)
    for mstockDic in mgrSeleList:
        profit = round(STOCKS_INST_DIC[mstockDic['symbol']].zf - mstockDic['zf'], 2)
        zjs, zf5js, ztjs, onemin_num = 0,0,0,0
        B, S = 0, 0
        # hap_pric_1 , hap_zf_m_1, hap_zf_1,hap_pric_2 , hap_zf_m_2, hap_zf_2 = -999,-999,-999,-999,-999,-999
        ask20, ask10 = 0, 0
        if 'zjs' in mstockDic:
            zjs = mstockDic['zjs'] 
        if 'zf5js' in mstockDic:
            zf5js = mstockDic['zf5js']
        if 'ztjs' in mstockDic:
            ztjs = mstockDic['ztjs']
        if 'onemin_num' in mstockDic:
            onemin_num = mstockDic['onemin_num']
        ####
        if 'hap_pric_1' in mstockDic:
            hap_pric_1 = mstockDic['hap_pric_1']
        if 'hap_zf_m_1' in mstockDic:
            hap_zf_m_1 = mstockDic['hap_zf_m_1']
        if 'hap_zf_1' in mstockDic:
            hap_zf_1 = mstockDic['hap_zf_1']
        #####
        if 'hap_pric_2' in mstockDic:
            hap_pric_2 = mstockDic['hap_pric_2']
        if 'hap_zf_m_2' in mstockDic:
            hap_zf_m_2 = mstockDic['hap_zf_m_2']
        if 'hap_zf_2' in mstockDic:
            hap_zf_2 = mstockDic['hap_zf_2']
        if 'ask20' in mstockDic:
            ask20 = mstockDic['ask20']
        if 'ask10' in mstockDic:
            ask10 = mstockDic['ask10']
        if 'B' in mstockDic:
            B = mstockDic['B']
        if 'S' in mstockDic:
            S = mstockDic['S']
        flg1 = mstockDic['buy_flag_1']
        day10bi = STOCKS_INST_DIC[mstockDic['symbol']].day10bi
        day20bi = STOCKS_INST_DIC[mstockDic['symbol']].day20bi
        day30bi = STOCKS_INST_DIC[mstockDic['symbol']].day30bi
        bdl_ma5 = STOCKS_INST_DIC[mstockDic['symbol']].bdl_ma5
        bdl_ma30 = STOCKS_INST_DIC[mstockDic['symbol']].bdl_ma30
        #
        bdl_ma5_2 = STOCKS_INST_DIC[mstockDic['symbol']].bdl_ma5_2
        bdl_ma30_2 = STOCKS_INST_DIC[mstockDic['symbol']].bdl_ma30_2
        day60bi = STOCKS_INST_DIC[mstockDic['symbol']].day60bi
        #
        open_zf = STOCKS_INST_DIC[mstockDic['symbol']].open_zf
        zt_cs = STOCKS_INST_DIC[mstockDic['symbol']].zt_cs
        zt_cs_60 = STOCKS_INST_DIC[mstockDic['symbol']].zt_cs_60
        zf_last_1 = STOCKS_INST_DIC[mstockDic['symbol']].zf_last_1


        relative_pos = STOCKS_INST_DIC[mstockDic['symbol']].relative_pos
        relative_pos2 = STOCKS_INST_DIC[mstockDic['symbol']].relative_pos2
        # tick
        open_price = STOCKS_INST_DIC[mstockDic['symbol']].open

        last_close = STOCKS_INST_DIC[mstockDic['symbol']].last_close

        # his
        ma5_c = STOCKS_INST_DIC[mstockDic['symbol']].ma5_c
        ma10_c = STOCKS_INST_DIC[mstockDic['symbol']].ma10_c
        ma20_c = STOCKS_INST_DIC[mstockDic['symbol']].ma20_c
        ma5_v = STOCKS_INST_DIC[mstockDic['symbol']].ma5_v
        ma10_v = STOCKS_INST_DIC[mstockDic['symbol']].ma10_v
        ma20_v = STOCKS_INST_DIC[mstockDic['symbol']].ma20_v

        lt_sz = round(STOCKS_INST_DIC[mstockDic['symbol']].ltp * ma5_c / 10000, 2)

        #20181101
        now_price = mstockDic['now']

        high_price = mstockDic['high']
        low_price = mstockDic['low']
        transaction_count = mstockDic['transaction_count']
        total_volume = mstockDic['total_volume']
        total_amount = mstockDic['total_amount']

        current_ask_amount = mstockDic['current_ask_amount']
        current_bid_amount = mstockDic['current_bid_amount']
        avrg_ask_price = mstockDic['avrg_ask_price']
        avrg_bid_price = mstockDic['avrg_bid_price']


        #20181101
        good_ticks_contin = mstockDic['good_ticks_contin']  # 连续tick
        good_ticks_cnt = mstockDic['good_ticks_cnt']  # 当前TICK 满足分钟量比<4 分钟hs>0.04 的TICK总数
        good_ticks_zf = mstockDic['good_ticks_zf']  # 当前tick的价格比上连续TICK的第一个价格的涨幅
        nowhigh = mstockDic['nowhigh']
        now_low_onemin = mstockDic['now_low_onemin']  # 5  增加分钟涨幅2  计算方法 计算当前价和一分钟最低价的涨幅。
        now_high_onemin = mstockDic['now_high_onemin']  # 6  增加分钟涨幅3   计算方法 计算当前价离一分钟最高价的涨幅
        bishu_div_sec = mstockDic['bishu_div_sec']  # 7  秒笔数：transection的数量除以总的秒数
        bishu_onemin = mstockDic['bishu_onemin']  # 8  当前分钟笔数：当前一分钟TRANSECTION的数量

        sendflg = 0
        if 'send' in mstockDic:
            sendflg = mstockDic['send']
        valueList = (
        mstockDic['symbol'], mstockDic['name'], mstockDic['time'], mstockDic['lb'], mstockDic['hs'], mstockDic['mhs'],
        mstockDic['askbidrate'],
        mstockDic['zf'], mstockDic['onemin'], mstockDic['zf_m'], mstockDic['nowMA5'], mstockDic['rank'],
        mstockDic['zt_good_rate'], mstockDic['zt_cnt'],
        mstockDic['b_name'],
        mstockDic['now'], flg1, profit, day10bi, day20bi, day30bi,day60bi,
        mstockDic['nowlowrate'], zf_last_1, bdl_ma5, bdl_ma30,bdl_ma5_2, bdl_ma30_2, open_zf, zt_cs, zt_cs_60, mstockDic['big_order_rate'],
        mstockDic['vol_inc_cnt'], lt_sz, relative_pos,relative_pos2,
        zjs,zf5js,ztjs,onemin_num,
        #tick
        open_price,high_price,low_price,last_close,
        transaction_count,total_volume,total_amount,current_ask_amount,
        current_bid_amount,avrg_ask_price,avrg_bid_price,
        #his
        ma5_c,ma10_c,ma20_c,ma5_v,ma10_v,ma20_v,

        # hap_pric_1, hap_zf_m_1, hap_zf_1, hap_pric_2, hap_zf_m_2, hap_zf_2,
        ask20,ask10,
        sendflg,back_test_day,STOCKS_INST_DIC[mstockDic['symbol']].one_min_total,
        B,S,good_ticks_contin,good_ticks_cnt,good_ticks_zf,nowhigh,now_low_onemin,
        now_high_onemin,bishu_div_sec,bishu_onemin,

        )
        alldatalist.append(valueList)

    if True:#len(mgrSeleList) > const.DISPLY_SELECT_MAX:  # save to csv
        try:
            if not os.path.exists(const.SELECT_TICKS_BACK + os.sep + str(back_test_day)):
                os.makedirs(const.SELECT_TICKS_BACK + os.sep + str(back_test_day))
            savepath = const.SELECT_TICKS_BACK + os.sep + str(back_test_day)+os.sep+'ticks_' + \
                       time.strftime("%H%M%S", time.localtime(time.time())) + '.csv'

            with open(savepath, 'w', newline='') as csvfile:
                writer = csv.writer(csvfile)
                writer.writerows(alldatalist)
        except Exception as e:
            MyUtil.print_error(e)


class ModulePickle(object):
    def __init__(self):
        self.buy_today_stocks_list = None

    def get_buy_today_list(self):
        return self.buy_today_stocks_list

    def set_buy_today_list(self,buy_today_stocks_list):
        self.buy_today_stocks_list = buy_today_stocks_list

    def SendOrder(self, mgrSel_cls, item):
        try:
            cnt = 0
            # print('item sel lst idx:', item['sel_lst_idx'])
            for config_item in self.buy_today_stocks_list:
                cnt += len(config_item)
            mgrSel_cls.SLECETION_LIST[item['sel_lst_idx']]['send'] = cnt+1
        except Exception as e:
            MyUtil.print_error(e)


CONFIG_ID=10
MAX_BUY_STOCKS_IDX=11
MAX_BUY_MONEY_IDX=12
OFFSET_BUY_PRICE_IDX=13
BUY_PRI_MAX_IDX = 14
BUY_PRI_MIN_IDX = 15

def TRADE_ST(mgrSel_cls, mTRADEAPI, config_tradeSt_list, redis_cls, local_time):

    try:
        buy_today_stocks_list = mTRADEAPI.get_buy_today_list()
        if buy_today_stocks_list==None:
            buy_today_stocks_list=[[] for i in range(1,const.CONFIG_NUMBER)]
            mTRADEAPI.set_buy_today_list(buy_today_stocks_list)
        buy_today_code_all = []
        for tradest_item in config_tradeSt_list:
            mconfig_id = tradest_item[CONFIG_ID]
            for item in buy_today_stocks_list[mconfig_id - 1]:
                buy_today_code_all.append(item[0])
        for tradest_item in config_tradeSt_list:
            mconfig_id = tradest_item[CONFIG_ID]
            if len(buy_today_stocks_list[mconfig_id-1]) >= tradest_item[MAX_BUY_STOCKS_IDX]:
                #print(u"今日买股数目已经达到上限:%i" % (MAX_BUY_STOCKS))
                continue
            mSLECETION_LIST = []
            for i in range(len(mgrSel_cls.SLECETION_LIST)):
                item = mgrSel_cls.SLECETION_LIST[i]
                if item['buy_flag_1']==mconfig_id:
                    item['sel_lst_idx'] = i
                    mSLECETION_LIST.append(item)
            localSLECETION_LIST = sorted(mSLECETION_LIST, key=lambda x: (x['zt_good_rate']), reverse=True)
            buy_today_code=[item[0] for item in buy_today_stocks_list[mconfig_id-1]]
            buyNum = len(buy_today_code)
            for item in localSLECETION_LIST:
                if not( item['symbol'] in buy_today_code) and buyNum<tradest_item[MAX_BUY_STOCKS_IDX] and not( item['symbol'] in buy_today_code_all):
                    mMAX_BUY_MONEY=tradest_item[MAX_BUY_MONEY_IDX]
                    offsetprice=tradest_item[OFFSET_BUY_PRICE_IDX]
                    price,num = getPriceAndVol(item['now'],mMAX_BUY_MONEY,offsetprice)
                    if price>tradest_item[BUY_PRI_MAX_IDX] or price<tradest_item[BUY_PRI_MIN_IDX]:
                        continue
                    if price>0 and num>0:
                        data = (item['symbol'], price, num, item['time'], mconfig_id)
                        print('send order :', item['symbol'], 'price:', price, 'number:',num )
                        #sStockCode,sPrice,sVolume
                        # nCategory
                        # 0 买入
                        # 1卖出
                        # nOrderType - 委托报价方式
                        # 0 限价委托； 上海限价委托/ 深圳限价委托
                        # -------------------------------------------------------query--------------------------------
                        # print('pre send order :', item['symbol'], 'price:', price, 'number:',num )
                        # start_time = time.time()
                        # redis_cls.__redis__.publish(const.QUERY_ZBCJ_SEND_CHANEL, item['symbol'])
                        # b_total, s_total, last_vol = 0, 0, 0
                        # # try:
                        # #     mgrSel_cls.query_tick_rcd[item['symbol']][1] = local_time
                        # # except Exception as e:
                        # #     MyUtil.print_error(e)
                        # try:
                        #     while 1:
                        #         parsed_msg = redis_cls.__mlistener__.get_message()
                        #         if parsed_msg and (parsed_msg['channel'] == const.QUERY_ZBCJ_RCV_CHANEL):
                        #             rec_data = parsed_msg['data']
                        #             if rec_data and type(rec_data) == str:
                        #                 b_total, s_total, last_vol = eval(rec_data)
                        #                 break
                        #         if time.time() - start_time > 1.5:
                        #             break
                        #     end_time = time.time()
                        #     mgrSel_cls.SLECETION_LIST[item['sel_lst_idx']]['b_total'] = b_total
                        #     mgrSel_cls.SLECETION_LIST[item['sel_lst_idx']]['s_total'] = s_total
                        #     mgrSel_cls.SLECETION_LIST[item['sel_lst_idx']]['last_vol'] = last_vol
                        #     print('query tick for trade cost time', 1000*(end_time - start_time),
                        #           'symbol:', item['symbol'],'b_total:', b_total, 's_total', s_total)
                        #     MyUtil.WrieTxtLogFile(str(item['symbol']) + 'send order failure because:' + 'b:' +
                        #                                str(b_total)+'s:' + str(s_total) + 'last_vol:'+str(last_vol))
                        # except Exception as e:
                        #     MyUtil.print_error(e)
                        # if 0 < b_total and 100*b_total/(b_total+s_total) < const.BS_PER:    # b_total==0 查询不到直接买
                        #     print('send order failure because b<s:', item['symbol'])
                        #     MyUtil.WrieTxtLogFile(str(item['symbol']) + 'send order failure because:' + 'b:' +
                        #                           str(b_total)+'s:' + str(s_total) + 'final_time:'+str(final_time))
                        #     continue
                        # -------------------------------------------------------query--------------------------------
                        # print('mgrSel_cls:',mgrSel_cls,'item:',item)
                        mTRADEAPI.SendOrder(mgrSel_cls, item)
                        buy_today_stocks_list[mconfig_id-1].append(data)
                        # try:
                        #     mgrSel_cls.query_tick_rcd[item['symbol']][0] = 1
                        # except Exception as e:
                        #     MyUtil.print_error(e)
                        try:
                            buy_today_code.append(item['symbol']) # add 20180403 bug for buy twice
                            buy_today_code_all.append(item['symbol'])
                        except:
                            pass
                        buyNum=buyNum+1

        mTRADEAPI.set_buy_today_list(buy_today_stocks_list)
    except Exception as e:
        MyUtil.print_error(e)



def getPriceAndVol(price, mMAX_BUY_MONEY, offsetprice):
    buy_numb = 0
    buy_price = 0
    try:
        X = round(mMAX_BUY_MONEY / float(price), 2)
        numb = 100
        if X > 100:
            numb = round(X / 100, 0) * 100

            newprice = price + offsetprice
            newprice_rnd = round(newprice, 2)
            buy_numb = numb
            buy_price=newprice_rnd
    except Exception as e:
        MyUtil.print_error(e)
    return buy_price,buy_numb

def merge_sele(TX_ONE_MIN_FLG):
    merge_lst = []
    if TX_ONE_MIN_FLG:
        files = os.listdir(const.SELECT_TICKS_BACK)
        for item in files:
            if '_profit' in item:
                merge_lst.append(item)
    if not merge_lst:
        return
    save_path= const.SELECT_TICKS_BACK
    df = pd.read_csv(save_path + os.sep + merge_lst[0], encoding='gbk')  # 编码默认UTF-8，若乱码自行更改
    save_name = 'large_' + time.strftime("%Y%m%d%H%M%S", time.localtime(time.time())) + '.csv'
    df.to_csv(save_path + os.sep + save_name, encoding="gbk", index=False)
    for i in range(1, len(merge_lst)):
        df = pd.read_csv(save_path + os.sep + merge_lst[i], encoding='gbk')
        df.to_csv(save_path + os.sep + save_name, encoding="gbk", index=False, header=False, mode='a+')
    print('merge finished')


def merger_csv(source_path, save_path, back_test_day):
    try:
        merge_lst = os.listdir(source_path)
        if not merge_lst:
            return
        df = pd.read_csv(source_path + os.sep + merge_lst[0], encoding='gbk')  # 编码默认UTF-8，若乱码自行更改
        save_name = 'backtest_' + back_test_day + '.csv'
        df.to_csv(save_path + os.sep + save_name, encoding="gbk", index=False)
        for i in range(1, len(merge_lst)):
            df = pd.read_csv(source_path + os.sep + merge_lst[i], encoding='gbk')
            df.to_csv(save_path + os.sep + save_name, encoding="gbk", index=False, header=False, mode='a+')
        print('merge finished')
    except Exception as e:
        print(e)

#
# def get_day_line_dic(k_line_folder):
#     day_line_dic = {}
#     k_line_files = os.listdir(k_line_folder)
#     for k_line_f in k_line_files:
#         df_tmp = pd.read_csv(k_line_folder + os.sep + k_line_f, encoding='gbk', dtype={'时间': int})
#         symbol = k_line_f.split('.')[0]  # '去掉.csv字段
#         # print('k_line_f:', k_line_f)
#         if symbol not in day_line_dic:
#             day_line_dic[symbol] = df_tmp


def calc_profit(merge_file, profit_csv_path, day_line_dic):

    df = pd.read_csv(merge_file, encoding='gbk')
    df['profit_open'] = 0.0
    df['profit_close'] = 0.0
    columns_list = df.columns.values.tolist()
    idx_buy_price = columns_list.index('买入价格')
    idx_date = columns_list.index('date')
    idx_symbol = columns_list.index('股票代码')
    idx_profit_open = columns_list.index('profit_open')
    idx_profit_close = columns_list.index('profit_close')
    # print('idx_date:', idx_date)

    for indexs in df.index:
        try:
            close_price=0
            line = df.loc[indexs].values
            symbol = str(line[idx_symbol]).zfill(6)
            m_date = int(line[idx_date])
            buy_price = line[idx_buy_price]
            if symbol in day_line_dic:
                if 'tommorow_o' in day_line_dic[symbol]:
                    open_price = day_line_dic[symbol]['tommorow_o']
                    df.iat[indexs, idx_profit_open] = round((100 * (open_price - buy_price) / buy_price), 2)
                if 'tommorow_c' in day_line_dic[symbol]:
                    close_price = day_line_dic[symbol]['tommorow_c']
                if 'today_close' in day_line_dic[symbol]:
                    close_price = day_line_dic[symbol]['today_close']
                if close_price==0:
                    df.iat[indexs, idx_profit_close] = 0.0001
                else:
                    df.iat[indexs, idx_profit_close] = round((100 * (close_price - buy_price) / buy_price), 2)
            else:
                df.iat[indexs, idx_profit_open] = 0.0001
                df.iat[indexs, idx_profit_close] = 0.0001
        except Exception as e:
            MyUtil.print_error(e)
            continue

    df.to_csv(profit_csv_path, encoding="gbk", index=False)

def set_newDic(symbol_tmp,mstock,STOCK_ONE_MIN_HIS,market):
    newDic = {}
    newDic['symbol'] = symbol_tmp
    newDic['name'] = mstock.name
    newDic['time'] = mstock.time
    newDic['now'] = mstock.now
    #
    newDic['high'] = mstock.high  # 20181101
    newDic['low'] = mstock.low  # 20181101
    newDic['transaction_count'] = mstock.transaction_count  # 20181101
    newDic['total_volume'] = mstock.total_volume  # 20181101
    newDic['total_amount'] = mstock.total_amount  # 20181101
    newDic['current_ask_amount'] = mstock.current_ask_amount  # 20181101
    newDic['current_bid_amount'] = mstock.current_bid_amount  # 20181101
    newDic['avrg_ask_price'] = mstock.avrg_ask_price  # 20181101
    newDic['avrg_bid_price'] = mstock.avrg_bid_price  # 20181101
    #
    newDic['good_ticks_contin'] = mstock.good_ticks_contin
    newDic['good_ticks_cnt'] = mstock.good_ticks_cnt
    newDic['good_ticks_zf'] = mstock.good_ticks_zf
    newDic['nowhigh'] = mstock.nowhigh
    newDic['now_low_onemin'] = mstock.now_low_onemin
    newDic['now_high_onemin'] = mstock.now_high_onemin
    newDic['bishu_div_sec'] = mstock.bishu_div_sec
    newDic['bishu_onemin'] = mstock.bishu_onemin
    #
    newDic['zf'] = mstock.zf
    newDic['lb'] = mstock.lb
    newDic['hs'] = mstock.hs
    newDic['mhs'] = mstock.mhs
    newDic['askbidrate'] = mstock.askbidrate
    newDic['onemin'] = mstock.onemin
    newDic['zf_m'] = mstock.zf_m
    newDic['nowMA5'] = mstock.nowMA5
    if mstock.zt_cnt > 0:
        newDic['zt_good_rate'] = round(mstock.zt_good / mstock.zt_cnt, 2)
    else:
        newDic['zt_good_rate'] = 0
    newDic['zt_cnt'] = mstock.zt_cnt
    rank_tmp = 99999
    for block_key in mstock.rank_in_block:
        if mstock.rank_in_block[block_key] < rank_tmp:
            rank_tmp = mstock.rank_in_block[block_key]
    newDic['rank'] = rank_tmp
    newDic['buy_flag_1'] = 0
    NOW_LOW_RATE = 0
    try:
        NOW_LOW_RATE = mstock.nowlowrate
    except Exception as e:
        pass
    newDic['nowlowrate'] = NOW_LOW_RATE
    newDic['big_order_rate'] = mstock.big_order_rate
    newDic['vol_inc_cnt'] = mstock.vol_inc_cnt
    last_zf_1 = 0
    try:
        last_zf_1 = mstock.zf_last_1
    except Exception as e:
        pass

    newDic['b_name'] = 'NO'
    newDic['b_zf'] = 0
    newDic['b_lb'] = 0
    newDic['b_zdrate'] = 0
    newDic['b_rank'] = 0
    if market:
        newDic['zjs'] = market.zjs
        newDic['zf5js'] = market.zf5js
        newDic['ztjs'] = market.ztjs
        newDic['onemin_num'] = market.onemin_num
    if len(STOCK_ONE_MIN_HIS) == 2:
        if symbol_tmp in STOCK_ONE_MIN_HIS[0]:  # (mstock.time,mstock.now,mstock.zf_m , mstock.zf)
            newDic['hap_pric_1'] = STOCK_ONE_MIN_HIS[0][symbol_tmp][1]
            newDic['hap_zf_m_1'] = STOCK_ONE_MIN_HIS[0][symbol_tmp][2]
            newDic['hap_zf_1'] = STOCK_ONE_MIN_HIS[0][symbol_tmp][3]
    if len(STOCK_ONE_MIN_HIS) == 3:
        if symbol_tmp in STOCK_ONE_MIN_HIS[1]:  # (mstock.time,mstock.now,mstock.zf_m , mstock.zf)
            newDic['hap_pric_1'] = STOCK_ONE_MIN_HIS[1][symbol_tmp][1]
            newDic['hap_zf_m_1'] = STOCK_ONE_MIN_HIS[1][symbol_tmp][2]
            newDic['hap_zf_1'] = STOCK_ONE_MIN_HIS[1][symbol_tmp][3]
        if symbol_tmp in STOCK_ONE_MIN_HIS[0]:  # (mstock.time,mstock.now,mstock.zf_m , mstock.zf)
            newDic['hap_pric_2'] = STOCK_ONE_MIN_HIS[0][symbol_tmp][1]
            newDic['hap_zf_m_2'] = STOCK_ONE_MIN_HIS[0][symbol_tmp][2]
            newDic['hap_zf_2'] = STOCK_ONE_MIN_HIS[0][symbol_tmp][3]
    # if symbol_tmp in ASK_BID_HIS:
    #     newDic['ASK20'] = ASK_BID_HIS[symbol_tmp][0]
    #     newDic['ASK10'] = ASK_BID_HIS[symbol_tmp][1]
    newDic['ask20'] = mstock.ask20
    newDic['ask10'] = mstock.ask10

    newDic['send'] = 1
    return newDic

def selection_auction(mgrSel_cls, STOCKS_INST_DIC, BLOCKS_INST_DIC, stock_lst, market,
              STOCK_ONE_MIN_HIS,ASK_BID_HIS, detail_tran):
    buy_flg = False
    if stock_lst == None:
        stock_lst = STOCKS_INST_DIC
    for symbol_tmp in stock_lst:
        try:
            mstock = STOCKS_INST_DIC[symbol_tmp]
            if '1' not in mstock.select_rcd_dic:
                mstock.select_rcd_dic['1'] = '92500'
            if mstock.select_rcd_dic['1'] == mstock.time:
                continue
            else:
                mstock.select_rcd_dic['1'] = mstock.time
            try:
                if 'S' in mstock.name:
                    continue
            except Exception as e:
                pass
            newDic = set_newDic(symbol_tmp, mstock, STOCK_ONE_MIN_HIS, market)
            mgrSel_cls.SLECETION_LIST.append(newDic)
        except Exception as e:
            MyUtil.print_error(e)
            continue


def selection(mgrSel_cls, STOCKS_INST_DIC, BLOCKS_INST_DIC, stock_lst, market,
              STOCK_ONE_MIN_HIS,ASK_BID_HIS, detail_tran):
    buy_flg = False
    if stock_lst == None:
        stock_lst = STOCKS_INST_DIC
    for symbol_tmp in stock_lst:
        try:
            mstock = STOCKS_INST_DIC[symbol_tmp]
            if '1' not in mstock.select_rcd_dic:
                mstock.select_rcd_dic['1'] = '93000'
            if mstock.select_rcd_dic['1'] == mstock.time:
                continue
            else :
                mstock.select_rcd_dic['1'] = mstock.time
            try:
                if 'S' in mstock.name:
                    continue
            except Exception as e:
                pass
            if not (0 < mstock.onemin < 4 and mstock.lb > 0):
                continue
            newDic = set_newDic(symbol_tmp,mstock,STOCK_ONE_MIN_HIS,market)
            if 0<mstock.onemin<4 and mstock.lb>0:
            #if mstock.askbidrate < 1 and mstock.zf < 2:
                B,S = detail_tran.get_zb_tick(str(symbol_tmp),str(mstock.time))
                newDic['B'] = B
                newDic['S'] = S
                mgrSel_cls.SLECETION_LIST.append(newDic)

        except Exception as e:
            MyUtil.print_error(e)
            continue

    return buy_flg

# 保存前一天和大前天的分钟量比数据,用于分析前一天分钟量比对今天的影响

def save_one_min_his(STOCKS_INST_DIC, STOCK_ONE_MIN_HIS, back_test_day):
    if STOCK_ONE_MIN_HIS == []:
        STOCK_ONE_MIN_HIS.append({})
        STOCK_ONE_MIN_HIS[0]['date'] = back_test_day
    if len(STOCK_ONE_MIN_HIS) == 1:
        if back_test_day != STOCK_ONE_MIN_HIS[0]['date']:
            STOCK_ONE_MIN_HIS.append({})
            STOCK_ONE_MIN_HIS[1]['date'] = back_test_day
    if len(STOCK_ONE_MIN_HIS) == 2:
        if back_test_day != STOCK_ONE_MIN_HIS[1]['date']:
            STOCK_ONE_MIN_HIS.append({})
            STOCK_ONE_MIN_HIS[2]['date'] = back_test_day
    if len(STOCK_ONE_MIN_HIS) == 3:
        if back_test_day != STOCK_ONE_MIN_HIS[2]['date']:
            STOCK_ONE_MIN_HIS.pop(0)
            STOCK_ONE_MIN_HIS.append({})
            STOCK_ONE_MIN_HIS[2]['date'] = back_test_day

    for symbol_tmp in STOCKS_INST_DIC:
        try:
            mstock = STOCKS_INST_DIC[symbol_tmp]
            if 0 < mstock.onemin < 4:
                if symbol_tmp not in STOCK_ONE_MIN_HIS[-1]:
                    STOCK_ONE_MIN_HIS[-1][symbol_tmp] = (mstock.time,mstock.now,mstock.zf_m, mstock.zf)
        except Exception as e:
            MyUtil.print_error(e)


def calc_ask_bid_10tick(stock_lst,ASK_BID_HIS): # 计算前10个tick内最大tick和当前的关系,跌幅超过一定范围则认为有效
    for symbol_tmp in stock_lst:
        mstock = stock_lst[symbol_tmp]
        max_askbid = 0
        max_askbid_20 = 0
        len_buffer = len(mstock.ticks_data_list)
        if len_buffer<20:
            continue
        for i in range(0,10):
            item = mstock.ticks_data_list[-i]
            if item['current_bid_amount']!=0:
                askbid = item['current_ask_amount']/item['current_bid_amount']
            else:
                askbid = 0
            if askbid > max_askbid:
                max_askbid = askbid
        max_askbid_20 = max_askbid
        for i in range(10, len_buffer):
            item = mstock.ticks_data_list[-i]
            if item['current_bid_amount']!=0:
                askbid = item['current_ask_amount']/item['current_bid_amount']
            else:
                askbid = 0
            if askbid > max_askbid_20:
                max_askbid_20=askbid
        ask20 = 0
        ask10 = 0
        if max_askbid_20>0:
            ask20 = (max_askbid_20 - mstock.askbidrate) / max_askbid_20
        if max_askbid>0:
            ask10 = (max_askbid - mstock.askbidrate) / max_askbid
        ASK_BID_HIS[symbol_tmp] = (ask20, ask10)




# def make_zjl_dic(source_folder = 'D:\\tick_zb\\沪深逐笔明细-20180809\\20180809', target_folder=const.ZJL):
#     #  制作资金流 文件名是股票, 字典key是日期,value是资金流入量
#     for zb_file in source_folder: # SH600000.TXT
#         df = pd.read_table(source_folder + os.sep + zb_file, encoding='gbk')
#         df0=df.apply(lambda df: df[1] * df[2], axis=1)
#         zjl_lst = df0.tolist()
#         zjl = 0
#         for item in zjl_lst:
#             zjl += item
#         if os.path.exists(target_folder + os.sep + zb_file[2:]):
#             info_dic = MyUtil.getInfo(target_folder + os.sep +zb_file[2:])
#             symbol = zb_file[2:8]
#             m_date = source_folder
#             if date_m not in info_dic:
#                 info_dic[date_m] = zjl
#             else:
#                 info_dic[date_m] = zjl



#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#                           制作除权因子 make_factor
#   绝对复权因子: 前复权的收盘价格/真实的价格
#   相对复权因子: 每天绝对复权因子*(1/最后一天绝对复权因子) 5日均价的话 N 取5
#
#
#
#
#
#

#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

def make_factor():
    pass



#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#                           获取逐笔历史数据
#
#   参数: stock,time
#   返回 B S S/B
#
#
#
#
#
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@


class DetailTran(object):
    def __init__(self, path_str, day_str):
        self.path_str = path_str
        self.day_str = day_str
        self.data_dic = {}

    def get_zb_tick(self,stock, time_str, length=1000):
        B, S = 0, 0
        if stock not in self.data_dic:
            SS = 'SZ'
            if stock[0] == 6 or stock[0] == '6':
                SS = 'SH'
            stock_file =  SS + stock + '.txt'
            if os.path.exists(self.path_str + os.sep + self.day_str + os.sep + stock_file):
                df = pd.read_table(self.path_str + os.sep + self.day_str + os.sep + stock_file,
                                   names=['time', 'close', 'vol'])
                df = df[df['time']<100000]  # 小于10点之前的数据
                df = df[df['time'] >= 93000]  # 大于93000点之前的数据
                self.data_dic[stock] = df
        if stock in self.data_dic:
            df_tmp = self.data_dic[stock]
            df_tmp_cut = df_tmp[df_tmp['time']<=int(time_str)]
            lines = df_tmp_cut.shape[0]
            if lines >= length:
                df_tmp_cut = df_tmp_cut.iloc[lines-length:lines-1]
            else:
                df_tmp_cut = df_tmp_cut.iloc[0:lines]

            df_tmp_cut_pos = df_tmp_cut[df_tmp_cut['vol']>0]  # 正数
            df_tmp_cut_neg = df_tmp_cut[df_tmp_cut['vol'] < 0]  # 负数
            B = df_tmp_cut_pos.iloc[:,2].sum()
            S = abs(df_tmp_cut_neg.iloc[:,2].sum())
        return B, S